# == Schema Information
# Schema version: 4
#
# Table name: feeds
#
#  id         :integer(11)     not null, primary key
#  url        :string(255)     default(""), not null
#  invalid    :boolean(1)      not null
#  title      :string(255)     
#  link       :string(255)     
#  created_at :datetime        
#  updated_at :datetime        
#


require 'open-uri'
require 'feed-normalizer'
require 'hpricot'

# News feeds that belongs to user/place/org and used for news stream about that objects
#  url: feed url
#  link: url of blog that feed belongs
class Feed < ActiveRecord::Base  
  has_many :posts

  validates_presence_of :url
  validates_uniqueness_of :url
  validate_on_create do |this|
    this.errors.add_to_base "Feed looks like invalid" unless !this.url.blank? && feed_valid?(this.url) 
  end
  
  def self.feed_valid?(url)
    r = load_feed_content(url)
    logger.info "DATA: #{r.to_s}"
    FeedNormalizer::FeedNormalizer.parse(r) != nil   
  end
  
  def self.receive_all
    find(:all, :order => 'id').each do |feed|
      begin
        feed.receive
      rescue Exception
        logger.error "ERROR to receive Feed##{feed.id} from #{feed.url}: #{$!.clean_message}\n" + $!.clean_backtrace.join("\n")
      end
    end
  end

  def receive    
    feed = FeedNormalizer::FeedNormalizer.parse(self.class.load_feed_content(url))
    self.update_attribute(:invalid, true) and return unless feed
    
    self.title = cleanup_text(feed.title)
    self.link = cleanup_text(feed.urls.first)

    last_published_post_at = self.posts.last.nil? ?nil: self.posts.last.published_at
    
    feed.items.reverse.each do |fe|
      published_at = Time.at(fe.date_published.to_i) #there are something strange with Time when it gets via build in ruby RSS parser
      
      if last_published_post_at.nil? or last_published_post_at < published_at
        fe.clean!
        post = posts.create :url => fe.url,
          :guid => fe.id,
          :title => fe.title,        
          :body => fe.content, 
          :published_at => published_at      
        if post.valid?          
          post.process
        else
          posts.delete(post) 
        end  
      end
    end
    save
  end
  
  protected
  def cleanup_text(text)
    return nil unless text
    text.gsub(/<\/?[^>]*>/, "").gsub(/\s{2,}/, ' ').strip
  end
  def self.load_feed_content(uri)
    open(uri.strip).read
  end
  
end

